package com.ex.web;

import com.ex.common.ResultData;
import com.ex.service.AccountService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Map;

/**
 * <h1>账户API</h1>
 *
 * @author longdeng
 * @Date 2019/10/7 20:16
 */
@Slf4j
@Api(value = "账户API", description = "账户API", tags = {"账户API"})
@RestController
@RequestMapping("/api/account")
public class AccountController {

    @Autowired
    private AccountService accountService;

    @ApiOperation("账户注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "string", paramType = "query")
    })
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public ResultData register(@RequestParam @ApiIgnore Map<String, String> map) {
        return accountService.register(map);
    }

    @ApiOperation("账户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "string", paramType = "query")
    })
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ResultData login(@RequestParam @ApiIgnore Map<String, String> map) {

        // 登录失败从request中获取shiro处理的异常信息。
        // shiroLoginFailure:就是shiro异常类的全类名.
        UsernamePasswordToken token = new UsernamePasswordToken(map.get("username"), map.get("password"));
        Subject currentUser = SecurityUtils.getSubject();
        try {
            currentUser.login(token);
        } catch (UnknownAccountException e) {
            /*
            UnknownAccountException            // 未知账户
            IncorrectCredentialsException      // 密码不正确
            LockedAccountException             // 账户被锁定
            ExcessiveAttemptsException         // 过度尝试异常
            AuthenticationException            // 验证异常
             */
            log.info("未知账户");
        } catch (IncorrectCredentialsException e) {
            log.info("密码不正确");
        } catch (LockedAccountException e) {
            log.info("账户被锁定");
        } catch (ExcessiveAttemptsException e) {
            log.info("过度尝试异常");
        } catch (AuthenticationException exception) {
            log.info("验证异常");
        }
        if (currentUser.isAuthenticated()) {
            return ResultData.success("登录成功");
        }
        return ResultData.error("登录失败");
    }

    @ApiOperation("测试接口")
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ResultData test(String value) {
        return ResultData.success("");
    }

}
